﻿using BCCommon;
using BCCommon.Enums;
using BCService;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using BCDto.Sim.Admin.Admin;
using BCDto.Website.User;
using BCService.Website.User;
using BCService.Sim.Admin.Admin;
using BCDto.Chats;
using BCCommon.Extensions;

namespace BCTMSRESTful.Configs
{
    public class WebContextService : IApplicationContextService
    {
        private readonly IHttpContextAccessor _httpContextAccessor;

        private AdminDto admin;
        private UserDto user;
        //private PartnerDto partner;
        //private DriverDto driver;
        //private SOBSettingDto sobSetting;
        private AnonymousDto anonymous;

        // 此构造函数不建议添加我们的接口，否则可能会造成循环依赖问题。
        // 作为替代方案，可以使用 _httpContextAccessor.HttpContext.RequestServices 获取所需要的服务。
        public WebContextService(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }

        public IServiceProvider RequestServices
        {
            get
            {
                return _httpContextAccessor.HttpContext.RequestServices;
            }
        }

        public AdminDto Admin
        {
            get
            {
                if (this.admin == null)
                {
                    this.ResolveUser();
                }
                return this.admin;
            }
        }

        public UserDto User
        {
            get
            {
                if (this.user == null)
                {
                    this.ResolveUser();
                }

                return this.user;
            }
        }

        //public PartnerDto Partner
        //{
        //    get
        //    {
        //        if (this.partner == null)
        //        {
        //            this.ResolvePartner();
        //        }

        //        return this.partner;
        //    }
        //}

        //public DriverDto Driver
        //{
        //    get
        //    {
        //        if (this.driver == null)
        //        {
        //            this.ResolveDriver();
        //        }

        //        return this.driver;
        //    }
        //}

        //public SOBSettingDto SobSetting
        //{
        //    get
        //    {
        //        if (this.sobSetting == null)
        //        {
        //            this.ResolveSobSetting();
        //        }

        //        return this.sobSetting;
        //    }
        //}

        public string IPAddress
        {
            get
            {
                var userHostAddress = _httpContextAccessor.HttpContext?.Request?.Headers["X-Forwarded-For"].FirstOrDefault();

                if (string.IsNullOrEmpty(userHostAddress))
                {
                    userHostAddress = _httpContextAccessor.HttpContext?.Connection?.RemoteIpAddress?.ToString();
                }

                return IPHelper.RemovePortNumber(userHostAddress);
            }
        }

        public AnonymousDto Anonymous
        {
            get
            {
                if (this.anonymous == null)
                {
                    this.ResolveUser();
                }

                return this.anonymous;
            }
        }

        private void ResolveUser()
        {
            if (_httpContextAccessor.HttpContext.WebSockets?.IsWebSocketRequest == true)
            {
                if (!_httpContextAccessor.HttpContext.Request.Query.ContainsKey("token"))
                {
                    return;
                }

                try
                {
                    var userId = TokenExtension.ResolveToken(_httpContextAccessor.HttpContext.Request.Query["token"], out var roleType);

                    if (roleType == RoleType.Anonymous)
                    {
                        this.anonymous = new AnonymousDto
                        {
                            AnonymousId = userId,
                            UserName = $"游客-{userId.ToString().Substring(userId.ToString().Length - 6)}"
                        };
                    }

                    if (roleType == RoleType.Admin)
                    {
                        this.admin = _httpContextAccessor.HttpContext.RequestServices.GetService<IAdminService>().GetAdminInfoByAdminId(userId);
                    }

                    if (roleType.In(RoleType.Partner, RoleType.Driver, RoleType.User))
                    {
                        this.user = _httpContextAccessor.HttpContext.RequestServices.GetService<IUserService>().GetUserByUserId(userId);
                    }
                }
                catch
                {
                    return;
                }
            }
            else
            {
                if (!_httpContextAccessor.HttpContext.User.Identity.IsAuthenticated)
                {
                    return;
                }

                if (_httpContextAccessor.HttpContext.User.Identity.Name.StartsWith($"{RoleType.Anonymous}:"))
                {
                    if (long.TryParse(_httpContextAccessor.HttpContext.User.Identity.Name.Substring(10), out long anonymousId))
                    {
                        this.anonymous = new AnonymousDto
                        {
                            AnonymousId = anonymousId,
                            UserName = $"游客-{anonymousId.ToString().Substring(anonymousId.ToString().Length - 6)}"
                        };
                    }
                }

                if (_httpContextAccessor.HttpContext.User.Identity.Name.StartsWith($"{RoleType.Admin}:"))
                {
                    if (long.TryParse(_httpContextAccessor.HttpContext.User.Identity.Name.Substring(6), out long adminId))
                    {
                        this.admin = _httpContextAccessor.HttpContext.RequestServices.GetService<IAdminService>().GetAdminInfoByAdminId(adminId);
                    }
                }

                //if (_httpContextAccessor.HttpContext.User.Identity.Name.StartsWith($"{RoleType.Partner}:"))
                //{
                //    if (long.TryParse(_httpContextAccessor.HttpContext.User.Identity.Name.Substring(8), out long userId))
                //    {
                //        this.user = _httpContextAccessor.HttpContext.RequestServices.GetService<IUserService>().GetUserByUserId(userId);
                //    }
                //}

                //if (_httpContextAccessor.HttpContext.User.Identity.Name.StartsWith($"{RoleType.Driver}:"))
                //{
                //    if (long.TryParse(_httpContextAccessor.HttpContext.User.Identity.Name.Substring(7), out long userId))
                //    {
                //        this.user = _httpContextAccessor.HttpContext.RequestServices.GetService<IUserService>().GetUserByUserId(userId);
                //    }
                //}

                if (_httpContextAccessor.HttpContext.User.Identity.Name.StartsWith($"{RoleType.User}:"))
                {
                    if (long.TryParse(_httpContextAccessor.HttpContext.User.Identity.Name.Substring(5), out long userId))
                    {
                        this.user = _httpContextAccessor.HttpContext.RequestServices.GetService<IUserService>().GetUserByUserId(userId);
                    }
                }
            }
        }

        //private void ResolvePartner()
        //{
        //    if (this.User?.Role != RoleType.Partner)
        //    {
        //        throw new ArgumentException("用户未登录或者当前登录的用户不是合伙人。");
        //    }

        //    this.partner = _httpContextAccessor.HttpContext.RequestServices.GetService<IPartnerService>().Get(this.user.PartnerId.Value);
        //}

        //private void ResolveDriver()
        //{
        //    if (this.User?.Role != RoleType.Driver)
        //    {
        //        throw new ArgumentException("用户未登录或者当前登录的用户不是司机。");
        //    }

        //    this.driver = _httpContextAccessor.HttpContext.RequestServices.GetService<IDriverService>().GetDriverByUserId(this.user.UserId);
        //}

        //private void ResolveSobSetting()
        //{
        //    if (this.Admin != null)
        //    {
        //        var sobSetting = _httpContextAccessor.HttpContext.RequestServices.GetService<ISOBSettingService>().GetEntity(this.admin.CompanyId);

        //        if (this.Admin.IsSystemAccount)
        //        {
        //            var systemAccountCachedSobSetting = _httpContextAccessor.HttpContext.RequestServices.GetService<IRedisService>().Get<SOBSettingDto>("SOBSetting_IsSystemAccount");

        //            if (systemAccountCachedSobSetting != null)
        //            {
        //                sobSetting = systemAccountCachedSobSetting;
        //            }
        //        }

        //        this.sobSetting = sobSetting;
        //    }

        //    if (this.User != null)
        //    {
        //        this.sobSetting = _httpContextAccessor.HttpContext.RequestServices.GetService<ISOBSettingService>().GetEntity(this.User.PartnerId.Value);
        //    }
        //}
    }
}
